#include "widget.h"
#include <QPainter>
#include <QMouseEvent>
#include <QDebug>
#include <QMessageBox>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    //600×600像素
    setFixedSize(widgetWidth,widgetHeight);

    setMouseTracking(true);

    //初始化游戏棋盘和棋子的情况,设为空白，储存为0
    for (int i = 0; i < 16; i++)
    {
        std::vector<int> lineBoard;
        for (int j = 0; j < 16; j++)
        {
            lineBoard.push_back(0);
        }
        gameMapVec.push_back(lineBoard);
    }

    //初始化tempMapVec用于临时存储
    for (int i = 0; i < 16; i++)
    {
        std::vector<int> lineBoard;
        for (int j = 0; j < 16; j++)
        {
            lineBoard.push_back(0);
        }
        tempMapVec.push_back(lineBoard);
    }

    //选择先手方
    int res = QMessageBox::question(this, tr("游戏开始"),tr("你想先手吗？"), QMessageBox::Yes, QMessageBox::No);
    if(res == QMessageBox::Yes)
    {
        PLAYER=-1;
        COMPUTER=1;
    }
    else
    {
        PLAYER=1;
        COMPUTER=-1;
    }

    if(COMPUTER==-1)
    {
        gameMapVec[7][7]=-1;
        order=1;
        update();
    }
}

Widget::~Widget()
{

}

void Widget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);

    QPainter painter(this);
    //反走样
    painter.setRenderHint(QPainter::Antialiasing, true);
    //设置画笔颜色
    painter.setPen(QColor(0, 0, 0));
    //绘制直线，棋盘16×16条线，每行每列各有15个格子
    for(int i=1;i<=16;i++)
    {
        painter.drawLine(QPointF(width()/17, (height()/17)*i), QPointF((width()/17)*16, (height()/17)*i));
        painter.drawLine(QPointF((width()/17)*i, height()/17), QPointF((width()/17)*i, (height()/17)*16));
    }

    //绘制棋子的准备
    QBrush brush;
    brush.setStyle(Qt::SolidPattern);

    int x,y;//棋子应该绘制的坐标

    for(int i=0;i<16;i++)
    {
        for (int j = 0; j < 16; j++)
        {
            if(gameMapVec[i][j]==1)//绘制白棋
            {
                brush.setColor(Qt::white);
                x=blockWidth*(j+1);
                y=blockWidth*(i+1);
                painter.setBrush(brush);
                painter.drawEllipse(QPointF(x, y), 10, 10);
            }
            if(gameMapVec[i][j]==-1)//绘制黑棋
            {
                brush.setColor(Qt::black);
                x=blockWidth*(j+1);
                y=blockWidth*(i+1);
                painter.setBrush(brush);
                painter.drawEllipse(QPointF(x, y), 10, 10);
            }
        }
    }
}

void Widget::mousePressEvent(QMouseEvent *event)
{
    int x = event->x();
    int y = event->y();

    if(event->button()==Qt::LeftButton)//按下鼠标左键
    {
        int row;//行（从0开始！按线来算）
        int col;//列（从0开始！按线来算）
        int pressAbleLength=blockWidth*16;//可以下棋子的长度
        int halfBlockWidth=blockWidth/2;

        if(x>=(widgetWidth-pressAbleLength)/2
                &&x<=(widgetWidth-pressAbleLength)/2+pressAbleLength
                &&y>=(widgetHeight-pressAbleLength)/2
                &&y<=(widgetHeight-pressAbleLength)/2+pressAbleLength)//点击在可下棋子的范围内
        {
            col=(x-halfBlockWidth)/blockWidth;
            row=(y-halfBlockWidth)/blockWidth;
            qDebug()<<"row:"<<row;
            qDebug()<<"col:"<<col;

            if(gameMapVec[row][col]==0)//如果点击的位置没有棋子才可以落子
            {
                if(order%2==0)//偶数下黑棋
                {
                    gameMapVec[row][col]=-1;
                    qDebug()<<gameMapVec[row][col];
                    order=1;
                }
                else if(order%2==1)//奇数下白棋
                {
                    gameMapVec[row][col]=1;
                    qDebug()<<gameMapVec[row][col];
                    order=0;
                }

                //更新棋子
                update();

                //输出输赢结果
                bool win=judgeWinner(row,col);
                if(win)
                {
                    if(gameMapVec[row][col]==-1)
                    {
                        qDebug()<<"balck win!";
                        QMessageBox::about(this, tr("游戏结束"), tr("黑棋获胜！"));
                    }
                    else if(gameMapVec[row][col]==1)
                    {
                        qDebug()<<"white win!";
                        QMessageBox::about(this, tr("游戏结束"), tr("白棋获胜！"));
                    }

                    //再来一局或者退出游戏
                    int res = QMessageBox::question(this, tr("游戏结束"),tr("再来一局吗？"), QMessageBox::Yes, QMessageBox::No);
                    if(res == QMessageBox::Yes)
                    {
                        //初始化棋盘数组
                        for(int i=0;i<16;i++)
                        {
                            for (int j = 0; j < 16; j++)
                            {
                                gameMapVec[i][j]=0;
                            }
                        }

                        //初始化tempMapVec数组
                        for(int i=0;i<16;i++)
                        {
                            for (int j = 0; j < 16; j++)
                            {
                                tempMapVec[i][j]=0;
                            }
                        }

                        //清空棋子图像
                        update();

                        //从黑棋开始下
                        order=0;

                        int res2 = QMessageBox::question(this, tr("游戏开始"),tr("你想先手吗？"), QMessageBox::Yes, QMessageBox::No);
                        if(res2 == QMessageBox::Yes)
                        {
                            PLAYER=-1;
                            COMPUTER=1;
                        }
                        else
                        {
                            PLAYER=1;
                            COMPUTER=-1;
                        }

                        if(COMPUTER==-1)
                        {
                            gameMapVec[7][7]=-1;
                            order=1;
                            update();
                        }

                        return; //避免了如果黑棋赢了，第二局先手会变白棋的情况
                    }
                    else
                    {
                        this->close();
                    }
                }

                isTimeToAI();
            }
        }
    }
}

bool Widget::judgeWinner(int row,int col)
{
    for (int i = 0; i < 5; i++)
    {
        if (col - i >= 0
                &&col - i + 4 <= 15
                &&gameMapVec[row][col - i] == gameMapVec[row][col - i + 1]
                &&gameMapVec[row][col - i] == gameMapVec[row][col - i + 2]
                &&gameMapVec[row][col - i] == gameMapVec[row][col - i + 3]
                &&gameMapVec[row][col - i] == gameMapVec[row][col - i + 4])
            return true;
    }

    for (int i = 0; i < 5; i++)
    {
        if (row - i >= 0
                &&row - i + 4 <= 15
                &&gameMapVec[row - i][col] == gameMapVec[row - i + 1][col]
                &&gameMapVec[row - i][col] == gameMapVec[row - i + 2][col]
                &&gameMapVec[row - i][col] == gameMapVec[row - i + 3][col]
                &&gameMapVec[row - i][col] == gameMapVec[row - i + 4][col])
            return true;
    }

    for (int i = 0; i < 5; i++)
    {
        if (row + i <= 15
                &&row + i - 4 >= 0
                &&col - i >= 0
                &&col - i + 4 <= 15
                &&gameMapVec[row + i][col - i] == gameMapVec[row + i - 1][col - i + 1]
                &&gameMapVec[row + i][col - i] == gameMapVec[row + i - 2][col - i + 2]
                &&gameMapVec[row + i][col - i] == gameMapVec[row + i - 3][col - i + 3]
                &&gameMapVec[row + i][col - i] == gameMapVec[row + i - 4][col - i + 4])
            return true;
    }

    for (int i = 0; i < 5; i++)
    {
        if (row - i >= 0
                &&row - i + 4 <= 15
                &&col - i >= 0
                &&col - i + 4 <= 15
                &&gameMapVec[row - i][col - i] == gameMapVec[row - i + 1][col - i + 1]
                &&gameMapVec[row - i][col - i] == gameMapVec[row - i + 2][col - i + 2]
                &&gameMapVec[row - i][col - i] == gameMapVec[row - i + 3][col - i + 3]
                &&gameMapVec[row - i][col - i] == gameMapVec[row - i + 4][col - i + 4])
            return true;
    }

    return false;
}

int Widget::getPointAt(Point p, int dir, int offset) //p为当前探测的中心点，dir为探测方向，offset是距离p的偏移量，返回值为该点的棋子类型（空、白棋、黑棋）
{
    int r = p.row;
    int c = p.col;

    r = r + offset*m_offset[dir].y();
    c = c + offset*m_offset[dir].x();

    if(r<0 || c<0 || r>=BOARDSIZE || c>=BOARDSIZE)
    {
        return -2;//OUTRANGE
    }

    return gameMapVec[r][c];
}

int Widget::evaluate(Point p,int who)   // 是哪一个玩家下在p位置
{
    int value = 0;

    int opposite = (who == PLAYER)?COMPUTER:PLAYER; // 敌对方是谁

    for(int i=0; i<8; i++)  // 8个方向
    {
        //*为待下棋子的点，1为己方棋子，2为对方棋子

        // 判断是否存在 *11110 ("活四" 必胜 没办法去堵了)
        if(getPointAt(p,i,1) == who && getPointAt(p,i,2) == who
                && getPointAt(p,i,3) == who && getPointAt(p,i,4) == who
                && getPointAt(p,i,5) == EMPTY)
        {
            value+=400000;  // 40万
        }

        // 判断是否存在 *11112 （死四A） 如果是己方则下子获得胜利，对手的话要竭力去堵
        if(getPointAt(p,i,1) == who &&getPointAt(p,i,2) == who
                && getPointAt(p,i,3) == who &&getPointAt(p,i,4) == who
                && getPointAt(p,i,5) == opposite)
        {
            value += 300000; // 30万
        }

        // 判断是否存在 1*111 （死四B）
        if(getPointAt(p,i,-1) == who &&getPointAt(p,i,1) == who
                && getPointAt(p,i,2) == who &&getPointAt(p,i,3) == who)
        {
            value += 300000; // 30万
        }

        // 判断是否存在 11*11 （死四C）
        if(getPointAt(p,i,-2) == who &&getPointAt(p,i,-1) == who
                && getPointAt(p,i,1) == who &&getPointAt(p,i,2) == who)
        {
            value += 300000; // 30万
        }

        // 判断是否存在 *1110 （活三A）
        if(getPointAt(p,i,1) == who &&getPointAt(p,i,2) == who
                && getPointAt(p,i,3) == who &&getPointAt(p,i,4) == EMPTY)
        {
            value += 200000; // 20万
        }

        // 判断是否存在 *10110 （活三B）
        if(getPointAt(p,i,1) == who &&getPointAt(p,i,2) == EMPTY
                && getPointAt(p,i,3) == who &&getPointAt(p,i,4) == who
                &&getPointAt(p,i,5) == EMPTY)
        {
            value += 200000; // 20万
        }

        // 判断是否存在 *1112 （死三A）
        if(getPointAt(p,i,1) == who &&getPointAt(p,i,2) == who
                && getPointAt(p,i,3) == who &&getPointAt(p,i,4) == opposite)
        {
            value += 100000; // 10万
        }

        // 判断是否存在 *10112 （死三B）
        if(getPointAt(p,i,1) == who &&getPointAt(p,i,2) == EMPTY
                && getPointAt(p,i,3) == who &&getPointAt(p,i,4) == who
                &&getPointAt(p,i,5) == opposite)
        {
            value += 100000; // 10万
        }

        // 判断是否存在 *11012 （死三C）
        if(getPointAt(p,i,1) == who &&getPointAt(p,i,2) == who
                && getPointAt(p,i,3) == EMPTY &&getPointAt(p,i,4) == who
                &&getPointAt(p,i,5) == opposite)
        {
            value += 100000; // 10万
        }

        // 判断是否存在 1*011 （死三D）
        if(getPointAt(p,i,-1) == who &&getPointAt(p,i,1) == EMPTY
                && getPointAt(p,i,2) == who &&getPointAt(p,i,3) == who)
        {
            value += 100000; // 10万
        }

        // 判断是否存在 1*101 （死三E）
        if(getPointAt(p,i,-1) == who &&getPointAt(p,i,1) == who
                && getPointAt(p,i,2) == EMPTY &&getPointAt(p,i,3) == who)
        {
            value += 100000; // 10万
        }

        // 判断是否存在 2*11102 （死三F）
        if(getPointAt(p,i,-1) == opposite &&getPointAt(p,i,1) == who
                && getPointAt(p,i,2) == who &&getPointAt(p,i,3) == who
                &&getPointAt(p,i,4) == EMPTY &&getPointAt(p,i,5) == opposite)
        {
            value += 100000; // 10万
        }

        // 判断是否存在 *01100 （活二A）
        if(getPointAt(p,i,1) == EMPTY && getPointAt(p,i,2) == who
                &&getPointAt(p,i,3) == who &&getPointAt(p,i,4) == EMPTY
                &&getPointAt(p,i,5) == EMPTY)
        {
            value += 10000; // 1万
        }

        // 判断是否存在 *1010 （活二B）
        if(getPointAt(p,i,1) == who && getPointAt(p,i,2) == EMPTY
                &&getPointAt(p,i,3) == who &&getPointAt(p,i,4) == EMPTY)
        {
            value += 10000; // 1万
        }

        // 判断是否存在 *10010 （活二C）
        if(getPointAt(p,i,1) == who && getPointAt(p,i,2) == EMPTY
                &&getPointAt(p,i,3) == EMPTY &&getPointAt(p,i,4) == who
                &&getPointAt(p,i,5) == EMPTY)
        {
            value += 10000; // 1万
        }

        // 判断是否存在 *00112（死二A）
        if(getPointAt(p,i,1) == EMPTY && getPointAt(p,i,2) == EMPTY
                && getPointAt(p,i,3) == who && getPointAt(p,i,4) == who
                && getPointAt(p,i,5) == opposite)
        {
            value +=100;
        }

        // 判断是否存在 *01012（死二B）
        if(getPointAt(p,i,1) == EMPTY && getPointAt(p,i,2) == who
                && getPointAt(p,i,3) == EMPTY && getPointAt(p,i,4) == who
                && getPointAt(p,i,5) == opposite)
        {
            value +=100;
        }

        // 判断是否存在 *10012（死二C）
        if(getPointAt(p,i,1) == who && getPointAt(p,i,2) == EMPTY
                && getPointAt(p,i,3) == EMPTY && getPointAt(p,i,4) == who
                && getPointAt(p,i,5) == opposite)
        {
            value +=100;
        }

        // 判断是否存在 1*001（死二D）
        if(getPointAt(p,i,-1) == who && getPointAt(p,i,1) == EMPTY
                && getPointAt(p,i,2) == EMPTY && getPointAt(p,i,3) == who)
        {
            value +=100;
        }


        // 周围如果已有棋子数目比较多的话，适当增加一下权值
        if(getPointAt(p,i,1)==who||getPointAt(p,i,-1)==opposite)
        {
            value +=10;
        }
    }

    return value;
}

bool Widget::isNotNull(Point p)
{
    if(gameMapVec[p.row][p.col]==0)
    {
        return false;
    }
    else
    {
        return true;
    }
}

void Widget::dropChessAt(Point p)
{
    if(order%2==0)//偶数下黑棋
    {
        gameMapVec[p.row][p.col]=-1;
        qDebug()<<"row:"<<p.row;
        qDebug()<<"col:"<<p.col;
        qDebug()<<gameMapVec[p.row][p.col];
        order=1;
    }
    else if(order%2==1)//奇数下白棋
    {
        gameMapVec[p.row][p.col]=1;
        qDebug()<<"row:"<<p.row;
        qDebug()<<"col:"<<p.col;
        qDebug()<<gameMapVec[p.row][p.col];
        order=0;
    }

    //更新棋子
    update();

    //输出输赢结果
    bool win=judgeWinner(p.row,p.col);
    if(win)
    {
        if(gameMapVec[p.row][p.col]==-1)
        {
            qDebug()<<"balck win!";
            QMessageBox::about(this, tr("游戏结束"), tr("黑棋获胜！"));
        }
        else if(gameMapVec[p.row][p.col]==1)
        {
            qDebug()<<"white win!";
            QMessageBox::about(this, tr("游戏结束"), tr("白棋获胜！"));
        }

        //再来一局或者退出游戏
        int res = QMessageBox::question(this, tr("游戏结束"),tr("再来一局吗？"), QMessageBox::Yes, QMessageBox::No);
        if(res == QMessageBox::Yes)
        {
            //初始化棋盘数组
            for(int i=0;i<16;i++)
            {
                for (int j = 0; j < 16; j++)
                {
                    gameMapVec[i][j]=0;
                }
            }
            //清空棋子图像
            update();

            //从黑棋开始下
            order=0;

            int res2 = QMessageBox::question(this, tr("游戏开始"),tr("你想先手吗？"), QMessageBox::Yes, QMessageBox::No);
            if(res2 == QMessageBox::Yes)
            {
                PLAYER=-1;
                COMPUTER=1;
            }
            else
            {
                PLAYER=1;
                COMPUTER=-1;
            }

            if(COMPUTER==-1)
            {
                gameMapVec[7][7]=-1;
                order=1;
                update();
            }
        }
        else
        {
            this->close();
        }
    }
}

void Widget::fakeDropChessAt(Point p,int object)//object是COMPUTER或者PLAYER，说明这次是模拟哪一方
{
    if(object==-1)//下黑棋
    {
        gameMapVec[p.row][p.col]=-1;
    }
    else if(object==1)//奇数下白棋
    {
        gameMapVec[p.row][p.col]=1;
    }
}

//轮到AI下棋
void Widget::isTimeToAI()
{
    dropChessAt(gameTreeBestPos());
}

//注意返回值是Point
Point Widget::gameTreeBestPos()
{
    std::vector<Node> rootNode; // 用于存储第一层的根节点
    std::vector<std::vector<int>> attackScoreMapVec; // 存储各个点位的进攻评分情况
    std::vector<std::vector<int>> defendScoreMapVec; // 存储各个点位的防守评分情况

    //初始化
    for (int i = 0; i < 16; i++)
    {
        std::vector<int> lineBoard;
        for (int j = 0; j < 16; j++)
        {
            lineBoard.push_back(0);
        }
        attackScoreMapVec.push_back(lineBoard);
    }

    //初始化
    for (int i = 0; i < 16; i++)
    {
        std::vector<int> lineBoard;
        for (int j = 0; j < 16; j++)
        {
            lineBoard.push_back(0);
        }
        defendScoreMapVec.push_back(lineBoard);
    }

    //将gameMapVec复制到tempMapVec
    for (int i = 0; i < 16; i++)
    {
        for (int j = 0; j < 16; j++)
        {
            tempMapVec[i][j]=gameMapVec[i][j];
        }
    }

    //由于AI第一步决策太慢，因此改为AI第一步只进行初级的决策（单层）
    int count=0;//统计人类棋子数目

    Point tempPoint(-1,-1);

    for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
    {
        for(int c=0; c<BOARDSIZE ;c++)
        {
            Point cur(r,c);  // 当前查询的位置

            if(isNotNull(cur)&&gameMapVec[r][c]==PLAYER)  // 如果有棋子并且是人类棋子
            {
                tempPoint.row=cur.row;
                tempPoint.col=cur.col;
                count++;
            }
        }
    }

    if(count==1)//人类下且仅下了一个棋子
    {
        for(int i=0;i<8;i++)
        {
            if(getPointAt(tempPoint,i,1)==0)
            {
                tempPoint.row+=m_offset[i].y();
                tempPoint.col+=m_offset[i].x();
            }
        }

        return tempPoint;
    }

    //(1)AI方遍历棋盘每个可以落子的点

    //检测己方死四和活四（一步制胜）
    int max1ofFirstLayer=0;

    for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
    {
        for(int c=0; c<BOARDSIZE ;c++)
        {
            Point cur(r,c);  // 当前查询的位置

            if(isNotNull(cur))  // 如果已经有棋子了
            {
                continue;
            }

            int value = evaluate(cur,COMPUTER);

            if(value>=300000)//value>=300000说明己方有死四或者活四，下这里可以直接胜利，不进行后续步骤
            {
                //将gameMapVec复制到tempMapVec
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        tempMapVec[i][j]=gameMapVec[i][j];
                    }
                }

                qDebug()<<"value:"<<value;
                return cur;
            }

            //求出最大进攻权值
            if(max1ofFirstLayer < value)
            {
                max1ofFirstLayer = value;
            }
        }
    }

    //检测对方死四和活四（己方没法一步制胜，必须防守）
    int max2ofFirstLayer=0;

    for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
    {
        for(int c=0; c<BOARDSIZE ;c++)
        {
            Point cur(r,c);  // 当前查询的位置

            if(isNotNull(cur))  // 如果已经有棋子了
            {
                continue;
            }

            int value2 = evaluate(cur,PLAYER);

            if(value2>=300000)//value>=300000说明对方有死四或者活四，必须防守
            {
                //将gameMapVec复制到tempMapVec
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        tempMapVec[i][j]=gameMapVec[i][j];
                    }
                }

                qDebug()<<"value2:"<<value2;
                return cur;
            }

            //求出最大进攻权值
            if(max2ofFirstLayer < value2)
            {
                max2ofFirstLayer = value2;
            }
        }
    }

    //检测活三，并且储存权值不为0即可以落子的点
    for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
    {
        for(int c=0; c<BOARDSIZE ;c++)
        {
            Point cur(r,c);  // 当前查询的位置

            if(isNotNull(cur))  // 如果已经有棋子了
            {
                continue;
            }

            int value = evaluate(cur,COMPUTER);

            if(value>=200000)//如果己方有活三（上面的遍历已经排除了对方有死四的情况）并且对方没有死四或者活四，下在这里即是制胜棋，不用进行后续步骤
            {
                //将gameMapVec复制到tempMapVec
                for (int i = 0; i < 16; i++)
                {
                    for (int j = 0; j < 16; j++)
                    {
                        tempMapVec[i][j]=gameMapVec[i][j];
                    }
                }

                qDebug()<<"value:"<<value;
                return cur;
            }

            int value2 = evaluate(cur,PLAYER);

            if(value>=0||value2>=0)//储存所有权值不为0的点
            {
                Node node(cur);
                rootNode.push_back(node);
            }
        }
    }

    //（2）假设AI已经落子，人类遍历棋盘每个可以落子的点并存储节点
    for(std::vector<Node>::iterator it=rootNode.begin();it!=rootNode.end();it++)
    {
        //假设落子
        fakeDropChessAt(it->p,COMPUTER);

        //进攻策略评估
        int max1 = 0;

        for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
        {
            for(int c=0; c<BOARDSIZE ;c++)
            {
                Point cur(r,c);  // 当前查询的位置

                if(isNotNull(cur))  // 如果已经有棋子了
                {
                    continue;
                }

                int value = evaluate(cur,PLAYER);//注意这里自己是PLAYER

                attackScoreMapVec[r][c]=value;

                if(max1<value)
                {
                    max1=value;
                }
            }
        }

        if(max1>=300000&&it!=rootNode.begin()-1)//value>=300000说明人类有死四；如果是rootNode最后一个则不能跳过
        {
            continue;
        }

        //防守策略评估
        int max2 = 0;

        for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
        {
            for(int c=0; c<BOARDSIZE ;c++)
            {
                Point cur(r,c);  // 当前查询的位置

                if(isNotNull(cur))  // 如果已经有棋子了
                {
                    continue;
                }

                int value = evaluate(cur,COMPUTER);//注意这里对手是COMPUTER

                defendScoreMapVec[r][c]=value;

                if(max2<value)
                {
                    max2=value;
                }
            }
        }

        if(max1>=200000&&max2<=300000) //进攻
        {
            //储存权值>=max-80的进攻下法
            for(int r=0; r<BOARDSIZE; r++)
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    if(attackScoreMapVec[r][c]>=max1-80)
                    {
                        Point p(r,c);
                        Node node(p);
                        node.f=&it;
                        (it->s).push_back(node);
                    }
                }
            }
        }
        else if(max2>=200000) //max2>=200000说明对方有活三
        {
            //储存权值>=max-80的防守下法
            for(int r=0; r<BOARDSIZE; r++)
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    if(attackScoreMapVec[r][c]>=max2-80)
                    {
                        Point p(r,c);
                        Node node(p);
                        node.f=&it;
                        (it->s).push_back(node);
                    }
                }
            }
        }
        else if(max1 >= max2) //进攻
        {
            //储存权值>=max-80的进攻下法
            for(int r=0; r<BOARDSIZE; r++)
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    if(attackScoreMapVec[r][c]>=max1-80)
                    {
                        Point p(r,c);
                        Node node(p);
                        node.f=&it;
                        (it->s).push_back(node);
                    }
                }
            }
        }
        else //防守
        {
            //储存权值>=max-80的防守下法
            for(int r=0; r<BOARDSIZE; r++)
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    if(attackScoreMapVec[r][c]>=max2-80)
                    {
                        Point p(r,c);
                        Node node(p);
                        node.f=&it;
                        (it->s).push_back(node);
                    }
                }
            }
        }

        //恢复gameMapVec
        for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
        {
            for(int c=0; c<BOARDSIZE ;c++)
            {
                gameMapVec[r][c]=tempMapVec[r][c];
            }
        }
    }

    //（3）假设人类已经落子，AI遍历棋盘每个可以落子的点并计算其权值
    Point bestPos1toDrop(-1,-1); // 最佳的进攻位置（第一层）
    Point bestPos2toDrop(-1,-1); // 最佳的防守位置（第一层）

    Point bestPos1ofAll(-1,-1);  // 最佳的进攻位置（第三层）
    Point bestPos2ofAll(-1,-1);  // 最佳的防守位置（第三层）

    int max1ofAll=0;
    int max2ofAll=0;

    //循环1（进攻判断）
    for(std::vector<Node>::iterator it=rootNode.begin();it!=rootNode.end();it++)
    {
        for(std::vector<Node>::iterator it2=(it->s).begin();it2!=(it->s).end();it2++)
        {
            //假设落子
            fakeDropChessAt(it->p,COMPUTER);
            fakeDropChessAt(it2->p,PLAYER);

            //进攻策略评估
            //int max1 = 0;

            for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    Point cur(r,c);  // 当前查询的位置

                    if(isNotNull(cur))  // 如果已经有棋子了
                    {
                        continue;
                    }

                    int value = evaluate(cur,COMPUTER);

                    if(max1ofAll < value)
                    {
                        max1ofAll = value;

                        bestPos1ofAll.row = cur.row;
                        bestPos1ofAll.col = cur.col;

                        bestPos1toDrop.row=(it->p).row;
                        bestPos1toDrop.col=(it->p).col;
                    }
                }
            }

            //恢复gameMapVec
            for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    gameMapVec[r][c]=tempMapVec[r][c];
                }
            }
        }
    }

    //循环2（防守判断）
    for(std::vector<Node>::iterator it=rootNode.begin();it!=rootNode.end();it++)
    {
        for(std::vector<Node>::iterator it2=(it->s).begin();it2!=(it->s).end();it2++)
        {
            //假设落子
            fakeDropChessAt(it->p,COMPUTER);
            fakeDropChessAt(it2->p,PLAYER);

            //防守策略评估
            //int max2=0;

            for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    Point cur(r,c);  // 当前查询的位置

                    if(isNotNull(cur))  // 如果已经有棋子了
                    {
                        continue;
                    }

                    int value = evaluate(cur,PLAYER);

                    if(max2ofAll < value)
                    {
                        max2ofAll = value;

                        bestPos2ofAll.row = cur.row;
                        bestPos2ofAll.col = cur.col;

                        bestPos2toDrop.row=(it->p).row;
                        bestPos2toDrop.col=(it->p).col;

                        if(max2ofAll>=400000&&max1ofAll<=300000) //如果人类已经有活三并且下在这里可以形成活四，并且AI没办法一步制胜，那么AI要抢占这个位置
                        {
                            //恢复gameMapVec
                            for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
                            {
                                for(int c=0; c<BOARDSIZE ;c++)
                                {
                                    gameMapVec[r][c]=tempMapVec[r][c];
                                }
                            }

                            return it2->p;
                        }
                    }
                }
            }

            //恢复gameMapVec
            for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
            {
                for(int c=0; c<BOARDSIZE ;c++)
                {
                    gameMapVec[r][c]=tempMapVec[r][c];
                }
            }
        }
    }

    // 从防守和进攻中找到最好的情况
    Point bestPostoDrop(-1,-1);//最佳位置（第一层）

    Point bestPosofAll(-1,-1);//最佳位置（第三层）

    if(max1ofAll>=300000) //max1>=300000说明己方有死四或者活四，下这里可以直接胜利
    {
        //dropChessAt(bestPos1);
        bestPosofAll.row=bestPos1ofAll.row;
        bestPosofAll.col=bestPos1ofAll.col;

        bestPostoDrop.row=bestPos1toDrop.row;
        bestPostoDrop.col=bestPos1toDrop.col;
    }
    else if(max1ofAll>=200000&&max2ofAll<=300000) //进攻
    {
        //dropChessAt(bestPos1);
        bestPosofAll.row=bestPos1ofAll.row;
        bestPosofAll.col=bestPos1ofAll.col;

        bestPostoDrop.row=bestPos1toDrop.row;
        bestPostoDrop.col=bestPos1toDrop.col;
    }
    else if(max2ofAll>=200000) //max2>=200000说明有活三，必须防守
    {
        //dropChessAt(bestPos2);
        bestPosofAll.row=bestPos2ofAll.row;
        bestPosofAll.col=bestPos2ofAll.col;

        bestPostoDrop.row=bestPos2toDrop.row;
        bestPostoDrop.col=bestPos2toDrop.col;
    }
    else if(max1ofAll >= max2ofAll) //进攻
    {
        //dropChessAt(bestPos1);
        bestPosofAll.row=bestPos1ofAll.row;
        bestPosofAll.col=bestPos1ofAll.col;

        bestPostoDrop.row=bestPos1toDrop.row;
        bestPostoDrop.col=bestPos1toDrop.col;
    }
    else //防守
    {
        //dropChessAt(bestPos2);
        bestPosofAll.row=bestPos2ofAll.row;
        bestPosofAll.col=bestPos2ofAll.col;

        bestPostoDrop.row=bestPos2toDrop.row;
        bestPostoDrop.col=bestPos2toDrop.col;
    }

    //为了修复AI会下在(-1,-1)坐标的bug而采取的投机取巧办法
    if(bestPostoDrop.row==-1&&bestPostoDrop.col==-1)
    {
        Point bestPos1(-1,-1);  // 最佳的进攻位置
        Point bestPos2(-1,-1);  // 最佳的防守位置

        // 首先，分析采取进攻策略时的情况
        // 当前棋盘中采取进攻策略的最高权重max1
        int max1 = 0;

        for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
        {
            for(int c=0; c<BOARDSIZE ;c++)
            {
                Point cur(r,c);  // 当前查询的位置

                if(isNotNull(cur))  // 如果已经有棋子了
                {
                    continue;
                }

                int value = evaluate(cur,COMPUTER);

                if(max1 < value)
                {
                    max1 = value;
                    bestPos1.row = cur.row;
                    bestPos1.col = cur.col;
                }
            }
        }

        // 然后，分析采取防守策略时的情况
        // 当前棋盘中采取防守策略的最高权重max2
        int max2 = 0;

        for(int r=0; r<BOARDSIZE; r++) // 双层循环遍历棋盘
        {
            for(int c=0; c<BOARDSIZE ;c++)
            {
                Point cur(r,c);  // 当前查询的位置

                if(isNotNull(cur))  // 如果已经有棋子了
                {
                    continue;
                }

                int value = evaluate(cur,PLAYER);

                if(max2 < value)
                {
                    max2 = value;
                    bestPos2.row = cur.row;
                    bestPos2.col = cur.col;
                }
            }
        }

        // 从防守和进攻中找到最好的情况
        if(max1>=300000) //max1>=300000说明己方有死四或者活四，下这里可以直接胜利
        {
            return bestPos1;
        }
        else if(max1>=200000&&max2<=300000)
        {
            return bestPos1;
        }
        else if(max2>=200000) //max2>=200000说明对方有活三
        {
            return bestPos2;
        }
        else if(max1 >= max2) //进攻
        {
            return bestPos1;
        }
        else //防守
        {
            return bestPos2;
        }
    }

    return bestPostoDrop;
}
